htmlwidgets, plotly, and highcharter for generating interactive graphics in Rlibrary(tidyverse)
library(knitr)
library(broom)
library(stringr)
library(modelr)
library(forcats)
library(haven)
library(plotly)
options(digits = 3)
set.seed(1234)
theme_set(theme_minimal())Overview first, zoom and filter, then details on demand
This mantra first coined by Ben Schneiderman (a professor of computer science) can be seen as a succinct summary of the purpose of data visualization:
Interactivity enhances our ability to accomplish the second point by presenting a structured way for readers to interact and explore the data, without having to know research design, computer programming, or other substantial technical skills that are a hurdle for the average reader. There are several design guidelines we can keep in mind as we design interactive graphics to keep them orderly and useful (rather than introducing interactivity that is pointless, confusing, or misleading).
Some visualizations will be linear - each step of the presentation depends on understanding the previous one. Others will be non-linear, giving the reader a choice in navigation and the direction of the story.
Think “choose your own adventure” stories.
Both approaches should utilize an introduction to setup the question and topic, but diverge quickly in the possible options the reader can explore.
Seeing Theory: A visual introduction to probability and statistics
shiny appshiny, ggplot2, plotly, and Excel(!)America’s Public Bible: Biblical Quotations in U.S. Newspapers
ggplot2 does not have built-in interactivity. The successor to ggplot2, ggvis, is still in development and not ready for production-level graphics.
However we can still build interactive graphics within the R environment. This is accomplished by a series of packages that generate JavaScript visualizations directly within R. JavaScript is a core technology within the World Wide Web framework, and is used to render websites. The majority of the demonstration visualizations above were created using JavaScript.
To build these types of graphs, we could shift entirely to an interactive graphics library based on Javascript, such as D3, and write all of our code in that format. The drawbacks to this approach are:
ggplot() makes many default assumptions when you write code to generate a graph. Normally the defaults work correctly, but you can always override them if necessary. With D3 and other JavaScript libraries, you cannot rely on these defaults.htmlwidgetshtmlwidgets is a framework for creating R bindings to JavaScript libraries. In essence, packages built on this framework take the R code that you write, process it, and convert it to the appropriate JavaScript code. From here, you can view the resulting graph in RStudio like an ordinary plot, embed it within an R Markdown document, or save it as a standalone .html page to share with others or post online.
Some of the packages we will explore this week are built using htmlwidgets; others use their own approach to bind R functions onto JavaScript libraries.
plotlyPlotly is an online analytics and data visualization tool built using Python, JavaScript, and D3. They offer a commercial product for designing graphics via a point-and-click interface online, but have developed open-source packages for generating plotly graphs (plotly.js), as well as API libraries for generating plotly graphs in R.
ggplotly()ggplot2 can be readily converted into interactive graphics in plotly through the use of ggplotly():
library(plotly)
# basic scatterplot
p <- ggplot(mpg, aes(displ, hwy)) +
geom_point()
ggplotly(p)# add color
p <- ggplot(mpg, aes(displ, hwy)) +
geom_point(aes(color = class))
ggplotly(p)# add smoothing line
ggplotly(p +
geom_smooth())# add vehicle labels to tooltips
p <- ggplot(mpg, aes(displ, hwy)) +
geom_point(aes(color = class, text = str_c(manufacturer, model, sep = " "))) +
geom_smooth()
ggplotly(p)# dahl bubbleplot
dahl <- read_dta("data/LittleDahl.dta")
dahl_mod <-lm(nulls ~ age + tenure + unified, data = dahl)
dahl_augment <- dahl %>%
mutate(hat = hatvalues(dahl_mod),
student = rstudent(dahl_mod),
cooksd = cooks.distance(dahl_mod))
# use size
p <- ggplot(dahl_augment, aes(hat, student)) +
geom_hline(yintercept = 0, linetype = 2) +
geom_point(aes(size = cooksd,
text = str_c(Congress, "Session of Congress", sep = " ")),
shape = 1) +
scale_size_continuous(range = c(1, 20)) +
labs(title = "Regression diagnostics for Dahl model",
x = "Leverage",
y = "Studentized residual") +
theme(legend.position = "none")
ggplotly(p)ggplotly() objectsstr(plotly_build(p))## List of 8
## $ x :List of 9
## ..$ data :List of 3
## .. ..$ :List of 12
## .. .. ..$ x : num [1:2] 0.00661 0.11829
## .. .. ..$ y : num [1:2] 0 0
## .. .. ..$ text : chr "yintercept: 0"
## .. .. ..$ type : chr "scatter"
## .. .. ..$ mode : chr "lines"
## .. .. ..$ line :List of 3
## .. .. .. ..$ width: num 1.89
## .. .. .. ..$ color: chr "rgba(0,0,0,1)"
## .. .. .. ..$ dash : chr "dash"
## .. .. ..$ hoveron : chr "points"
## .. .. ..$ showlegend: logi FALSE
## .. .. ..$ xaxis : chr "x"
## .. .. ..$ yaxis : chr "y"
## .. .. ..$ hoverinfo : chr "text"
## .. .. ..$ frame : chr NA
## .. ..$ :List of 12
## .. .. ..$ x : num [1:104] 0.0974 0.0664 0.1132 0.0524 0.0563 ...
## .. .. ..$ y : num [1:104] 0.3301 -0.0277 0.5113 -0.0148 0.1631 ...
## .. .. ..$ text : chr [1:104] "cooksd: 2.96e-03<br />hat: 0.0974<br />student: 0.33012" "cooksd: 1.38e-05<br />hat: 0.0664<br />student: -0.02775" "cooksd: 8.41e-03<br />hat: 0.1132<br />student: 0.51131" "cooksd: 3.07e-06<br />hat: 0.0524<br />student: -0.01482" ...
## .. .. ..$ type : chr "scatter"
## .. .. ..$ mode : chr "markers"
## .. .. ..$ marker :List of 6
## .. .. .. ..$ autocolorscale: logi FALSE
## .. .. .. ..$ color : chr "rgba(0,0,0,1)"
## .. .. .. ..$ opacity : num 1
## .. .. .. ..$ size : num [1:104] 12.06 4.34 17.72 4.03 6.82 ...
## .. .. .. ..$ symbol : chr "circle-open"
## .. .. .. ..$ line :List of 2
## .. .. .. .. ..$ width: num 1.89
## .. .. .. .. ..$ color: chr "rgba(0,0,0,1)"
## .. .. ..$ hoveron : chr "points"
## .. .. ..$ showlegend: logi FALSE
## .. .. ..$ xaxis : chr "x"
## .. .. ..$ yaxis : chr "y"
## .. .. ..$ hoverinfo : chr "text"
## .. .. ..$ frame : chr NA
## .. ..$ :List of 12
## .. .. ..$ x : num [1:10] 0.0514 0.073 0.0208 0.0361 0.102 ...
## .. .. ..$ y : num [1:10] 4.42 3.02 4.48 2.14 -1.07 ...
## .. .. ..$ text : chr [1:10] "74th" "98th" "104th" "67th" ...
## .. .. ..$ textfont :List of 2
## .. .. .. ..$ size : num 14.7
## .. .. .. ..$ color: chr "rgba(0,0,0,1)"
## .. .. ..$ type : chr "scatter"
## .. .. ..$ mode : chr "text"
## .. .. ..$ hoveron : chr "points"
## .. .. ..$ showlegend: logi FALSE
## .. .. ..$ xaxis : chr "x"
## .. .. ..$ yaxis : chr "y"
## .. .. ..$ hoverinfo : chr "text"
## .. .. ..$ frame : chr NA
## ..$ layout :List of 8
## .. ..$ margin :List of 4
## .. .. ..$ t: num 26.2
## .. .. ..$ r: num 7.31
## .. .. ..$ b: num 40.2
## .. .. ..$ l: num 31.4
## .. ..$ font :List of 3
## .. .. ..$ color : chr "rgba(0,0,0,1)"
## .. .. ..$ family: chr ""
## .. .. ..$ size : num 14.6
## .. ..$ xaxis :List of 25
## .. .. ..$ domain : num [1:2] 0 1
## .. .. ..$ type : chr "linear"
## .. .. ..$ autorange : logi FALSE
## .. .. ..$ tickmode : chr "array"
## .. .. ..$ range : num [1:2] 0.00661 0.11829
## .. .. ..$ ticktext : chr [1:3] "0.03" "0.06" "0.09"
## .. .. ..$ tickvals : num [1:3] 0.03 0.06 0.09
## .. .. ..$ ticks : chr ""
## .. .. ..$ tickcolor : logi NA
## .. .. ..$ ticklen : num 3.65
## .. .. ..$ tickwidth : num 0
## .. .. ..$ showticklabels: logi TRUE
## .. .. ..$ tickfont :List of 3
## .. .. .. ..$ color : chr "rgba(77,77,77,1)"
## .. .. .. ..$ family: chr ""
## .. .. .. ..$ size : num 11.7
## .. .. ..$ tickangle : num 0
## .. .. ..$ showline : logi FALSE
## .. .. ..$ linecolor : logi NA
## .. .. ..$ linewidth : num 0
## .. .. ..$ showgrid : logi TRUE
## .. .. ..$ gridcolor : chr "rgba(235,235,235,1)"
## .. .. ..$ gridwidth : num 0.664
## .. .. ..$ zeroline : logi FALSE
## .. .. ..$ anchor : chr "y"
## .. .. ..$ title : chr "Leverage"
## .. .. ..$ titlefont :List of 3
## .. .. .. ..$ color : chr "rgba(0,0,0,1)"
## .. .. .. ..$ family: chr ""
## .. .. .. ..$ size : num 14.6
## .. .. ..$ hoverformat : chr ".2f"
## .. ..$ yaxis :List of 25
## .. .. ..$ domain : num [1:2] 0 1
## .. .. ..$ type : chr "linear"
## .. .. ..$ autorange : logi FALSE
## .. .. ..$ tickmode : chr "array"
## .. .. ..$ range : num [1:2] -1.98 4.79
## .. .. ..$ ticktext : chr [1:3] "0" "2" "4"
## .. .. ..$ tickvals : num [1:3] 0 2 4
## .. .. ..$ ticks : chr ""
## .. .. ..$ tickcolor : logi NA
## .. .. ..$ ticklen : num 3.65
## .. .. ..$ tickwidth : num 0
## .. .. ..$ showticklabels: logi TRUE
## .. .. ..$ tickfont :List of 3
## .. .. .. ..$ color : chr "rgba(77,77,77,1)"
## .. .. .. ..$ family: chr ""
## .. .. .. ..$ size : num 11.7
## .. .. ..$ tickangle : num 0
## .. .. ..$ showline : logi FALSE
## .. .. ..$ linecolor : logi NA
## .. .. ..$ linewidth : num 0
## .. .. ..$ showgrid : logi TRUE
## .. .. ..$ gridcolor : chr "rgba(235,235,235,1)"
## .. .. ..$ gridwidth : num 0.664
## .. .. ..$ zeroline : logi FALSE
## .. .. ..$ anchor : chr "x"
## .. .. ..$ title : chr "Studentized residual"
## .. .. ..$ titlefont :List of 3
## .. .. .. ..$ color : chr "rgba(0,0,0,1)"
## .. .. .. ..$ family: chr ""
## .. .. .. ..$ size : num 14.6
## .. .. ..$ hoverformat : chr ".2f"
## .. ..$ shapes :List of 1
## .. .. ..$ :List of 9
## .. .. .. ..$ type : chr "rect"
## .. .. .. ..$ fillcolor: logi NA
## .. .. .. ..$ line :List of 3
## .. .. .. .. ..$ color : logi NA
## .. .. .. .. ..$ width : num 0
## .. .. .. .. ..$ linetype: chr(0)
## .. .. .. ..$ yref : chr "paper"
## .. .. .. ..$ xref : chr "paper"
## .. .. .. ..$ x0 : num 0
## .. .. .. ..$ x1 : num 1
## .. .. .. ..$ y0 : num 0
## .. .. .. ..$ y1 : num 1
## .. ..$ showlegend: logi FALSE
## .. ..$ legend :List of 4
## .. .. ..$ bgcolor : logi NA
## .. .. ..$ bordercolor: logi NA
## .. .. ..$ borderwidth: num 0
## .. .. ..$ font :List of 3
## .. .. .. ..$ color : chr "rgba(0,0,0,1)"
## .. .. .. ..$ family: chr ""
## .. .. .. ..$ size : num 11.7
## .. ..$ hovermode : chr "closest"
## ..$ source : chr "A"
## ..$ attrs :List of 3
## .. ..$ 832f7bfcfea3:List of 2
## .. .. ..$ yintercept:Class 'formula' language ~yintercept
## .. .. .. .. ..- attr(*, ".Environment")=<environment: 0x7fdc5819c660>
## .. .. ..$ type : chr "ggplotly"
## .. .. ..- attr(*, "class")= chr "plotly_eval"
## .. ..$ 832f1eb1beed:List of 3
## .. .. ..$ size:Class 'formula' language ~cooksd
## .. .. .. .. ..- attr(*, ".Environment")=<environment: 0x7fdc581a5f40>
## .. .. ..$ x :Class 'formula' language ~hat
## .. .. .. .. ..- attr(*, ".Environment")=<environment: 0x7fdc581a5f40>
## .. .. ..$ y :Class 'formula' language ~student
## .. .. .. .. ..- attr(*, ".Environment")=<environment: 0x7fdc581a5f40>
## .. .. ..- attr(*, "class")= chr "plotly_eval"
## .. ..$ 832f276dc959:List of 3
## .. .. ..$ label:Class 'formula' language ~Congress
## .. .. .. .. ..- attr(*, ".Environment")=<environment: 0x7fdc581cbf40>
## .. .. ..$ x :Class 'formula' language ~hat
## .. .. .. .. ..- attr(*, ".Environment")=<environment: 0x7fdc581cbf40>
## .. .. ..$ y :Class 'formula' language ~student
## .. .. .. .. ..- attr(*, ".Environment")=<environment: 0x7fdc581cbf40>
## .. .. ..- attr(*, "class")= chr "plotly_eval"
## ..$ cur_data : chr "832f7bfcfea3"
## ..$ visdat :List of 3
## .. ..$ 832f7bfcfea3:function (y)
## .. ..$ 832f1eb1beed:function (y)
## .. ..$ 832f276dc959:function (y)
## ..$ config :List of 2
## .. ..$ modeBarButtonsToAdd:List of 1
## .. .. ..$ :List of 3
## .. .. .. ..$ name : chr "Collaborate"
## .. .. .. ..$ icon :List of 4
## .. .. .. .. ..$ width : num 1000
## .. .. .. .. ..$ ascent : num 500
## .. .. .. .. ..$ descent: num -50
## .. .. .. .. ..$ path : chr "M487 375c7-10 9-23 5-36l-79-259c-3-12-11-23-22-31-11-8-22-12-35-12l-263 0c-15 0-29 5-43 15-13 10-23 23-28 37-5 13-5 25-1 37 0 0"| __truncated__
## .. .. .. ..$ click:Class 'JS_EVAL' chr "function(gd) { \n // is this being viewed in RStudio?\n if (location.search == '?viewer_pane=1') {\n ale"| __truncated__
## .. ..$ cloud : logi FALSE
## ..$ highlight:List of 6
## .. ..$ on : chr "plotly_click"
## .. ..$ persistent: logi FALSE
## .. ..$ dynamic : logi FALSE
## .. ..$ selectize : logi FALSE
## .. ..$ opacityDim: num 0.2
## .. ..$ selected :List of 1
## .. .. ..$ opacity: num 1
## ..$ base_url : chr "https://plot.ly"
## ..- attr(*, "TOJSON_FUNC")=function (x, ...)
## $ width : NULL
## $ height : NULL
## $ sizingPolicy :List of 6
## ..$ defaultWidth : chr "100%"
## ..$ defaultHeight: num 400
## ..$ padding : NULL
## ..$ viewer :List of 6
## .. ..$ defaultWidth : NULL
## .. ..$ defaultHeight: NULL
## .. ..$ padding : NULL
## .. ..$ fill : logi TRUE
## .. ..$ suppress : logi FALSE
## .. ..$ paneHeight : NULL
## ..$ browser :List of 4
## .. ..$ defaultWidth : NULL
## .. ..$ defaultHeight: NULL
## .. ..$ padding : NULL
## .. ..$ fill : logi TRUE
## ..$ knitr :List of 3
## .. ..$ defaultWidth : NULL
## .. ..$ defaultHeight: NULL
## .. ..$ figure : logi TRUE
## $ dependencies :List of 3
## ..$ :List of 10
## .. ..$ name : chr "jquery"
## .. ..$ version : chr "1.11.3"
## .. ..$ src :List of 1
## .. .. ..$ file: chr "/Library/Frameworks/R.framework/Versions/3.3/Resources/library/crosstalk/lib/jquery"
## .. ..$ meta : NULL
## .. ..$ script : chr "jquery.min.js"
## .. ..$ stylesheet: NULL
## .. ..$ head : NULL
## .. ..$ attachment: NULL
## .. ..$ package : NULL
## .. ..$ all_files : logi TRUE
## .. ..- attr(*, "class")= chr "html_dependency"
## ..$ :List of 10
## .. ..$ name : chr "crosstalk"
## .. ..$ version : chr "1.0.0"
## .. ..$ src :List of 1
## .. .. ..$ file: chr "/Library/Frameworks/R.framework/Versions/3.3/Resources/library/crosstalk/www"
## .. ..$ meta : NULL
## .. ..$ script : chr "js/crosstalk.min.js"
## .. ..$ stylesheet: chr "css/crosstalk.css"
## .. ..$ head : NULL
## .. ..$ attachment: NULL
## .. ..$ package : NULL
## .. ..$ all_files : logi TRUE
## .. ..- attr(*, "class")= chr "html_dependency"
## ..$ :List of 10
## .. ..$ name : chr "typedarray"
## .. ..$ version : chr "0.1"
## .. ..$ src :List of 1
## .. .. ..$ file: chr "/Library/Frameworks/R.framework/Versions/3.3/Resources/library/plotly/htmlwidgets/lib/typedarray"
## .. ..$ meta : NULL
## .. ..$ script : chr "typedarray.min.js"
## .. ..$ stylesheet: NULL
## .. ..$ head : NULL
## .. ..$ attachment: NULL
## .. ..$ package : NULL
## .. ..$ all_files : logi TRUE
## .. ..- attr(*, "class")= chr "html_dependency"
## $ elementId : chr "832f18be0648"
## $ preRenderHook:function (p, registerFrames = TRUE)
## $ jsHooks :List of 1
## ..$ render:List of 1
## .. ..$ :List of 2
## .. .. ..$ code: chr "function(el, x) { var ctConfig = crosstalk.var('plotlyCrosstalkOpts').set({\"on\":\"plotly_click\",\"persistent\":false,\"dynam"| __truncated__
## .. .. ..$ data: NULL
## - attr(*, "class")= chr [1:2] "plotly" "htmlwidget"
## - attr(*, "package")= chr "plotly"
ggplotly() stores all the components of the graph in a list object in R, which you can directly access using plotly_build(). To modify components of the ggplotly() object, “simply” modify the appropriate element in plotly_build(). Let’s use the OTC tax widget as an example, converting it into a non-Shiny object.1
library(tidyverse)
library(stringr)
library(plotly)
library(rJava)
library(XLConnect)
options(digits = 3)
set.seed(1234)
theme_set(theme_minimal())
# function to convert outputs to tidy data frame
tidy_outputs <- function(outputs){
outputs %>%
as_tibble %>%
gather(year, value, -Revenue.effect, convert = TRUE) %>%
mutate(year = parse_number(year),
Revenue.effect = factor(Revenue.effect,
levels = c("User Model",
"The Joint Committee on Taxation",
"The Lindsey Group")))
}
# load model workbook and default inputs and outputs
# sorry i cannot share this file with you - it's proprietary
model <- loadWorkbook("data/OTCModelFeb2017rev5-Widget.xlsx")
model_inputs <- readWorksheet(model, "R-in")
# create color palette for graph
cbbpal <- c('#1b9e77', '#d95f02', '#7570b3')
# generate data
model_data <- tidy_outputs(readWorksheet(model, "R-out"))
model_data
# generate basic graph
g <- model_data %>%
rename(Year = year, `Revenue effect` = value, `Model` = Revenue.effect) %>%
ggplot(aes(Year, `Revenue effect`, color = Model)) +
geom_line(size = 1.5) +
scale_color_manual(values = cbbpal) +
guides(color = guide_legend(nrow = 1)) +
labs(x = "Year",
y = "Millions (USD)",
color = NULL) +
theme_minimal(base_size = 14)
# static version
g
# plotly version
p <- plotly_build(g)
p
# view legend components
p$x$layout$legend
# fix legend position
p$x$layout$legend$x <- .5
p$x$layout$legend$y <- -.3
p$x$layout$legend$xanchor <- "center"
p$x$layout$legend$yanchor <- "top"
p$x$layout$legend$orientation <- "h"
p
# view structure
p$x$data[[1]]
# need to change the $text element - written in html
p$x$data[[1]]$text <- str_replace_all(p$x$data[[1]]$text,
pattern = "`Revenue effect`", "Revenue effect")
p$x$data[[2]]$text <- str_replace_all(p$x$data[[2]]$text,
pattern = "`Revenue effect`", "Revenue effect")
p$x$data[[3]]$text <- str_replace_all(p$x$data[[3]]$text,
pattern = "`Revenue effect`", "Revenue effect")
pdevtools::session_info()## setting value
## version R version 3.3.3 (2017-03-06)
## system x86_64, darwin13.4.0
## ui X11
## language (EN)
## collate en_US.UTF-8
## tz America/Chicago
## date 2017-05-01
##
## package * version date source
## assertthat 0.2.0 2017-04-11 cran (@0.2.0)
## backports 1.0.5 2017-01-18 CRAN (R 3.3.2)
## broom * 0.4.2 2017-02-13 CRAN (R 3.3.2)
## codetools 0.2-15 2016-10-05 CRAN (R 3.3.3)
## colorspace 1.3-2 2016-12-14 CRAN (R 3.3.2)
## crosstalk 1.0.0 2016-12-21 CRAN (R 3.3.2)
## DBI 0.6 2017-03-09 CRAN (R 3.3.3)
## devtools 1.12.0 2016-06-24 CRAN (R 3.3.0)
## digest 0.6.12 2017-01-27 CRAN (R 3.3.2)
## dplyr * 0.5.0 2016-06-24 CRAN (R 3.3.0)
## evaluate 0.10 2016-10-11 CRAN (R 3.3.0)
## forcats * 0.2.0 2017-01-23 CRAN (R 3.3.2)
## foreign 0.8-67 2016-09-13 CRAN (R 3.3.3)
## ggplot2 * 2.2.1.9000 2017-05-01 Github (hadley/ggplot2@f4398b6)
## gtable 0.2.0 2016-02-26 CRAN (R 3.3.0)
## haven * 1.0.0 2016-09-23 cran (@1.0.0)
## hms 0.3 2016-11-22 CRAN (R 3.3.2)
## htmltools 0.3.6 2017-04-28 cran (@0.3.6)
## htmlwidgets 0.8 2016-11-09 CRAN (R 3.3.1)
## httpuv 1.3.3 2015-08-04 CRAN (R 3.3.0)
## httr 1.2.1 2016-07-03 CRAN (R 3.3.0)
## jsonlite 1.4 2017-04-08 cran (@1.4)
## knitr * 1.15.1 2016-11-22 cran (@1.15.1)
## labeling 0.3 2014-08-23 CRAN (R 3.3.0)
## lattice 0.20-34 2016-09-06 CRAN (R 3.3.3)
## lazyeval 0.2.0 2016-06-12 CRAN (R 3.3.0)
## lubridate 1.6.0 2016-09-13 CRAN (R 3.3.0)
## magrittr 1.5 2014-11-22 CRAN (R 3.3.0)
## memoise 1.0.0 2016-01-29 CRAN (R 3.3.0)
## mime 0.5 2016-07-07 CRAN (R 3.3.0)
## mnormt 1.5-5 2016-10-15 CRAN (R 3.3.0)
## modelr * 0.1.0 2016-08-31 CRAN (R 3.3.0)
## munsell 0.4.3 2016-02-13 CRAN (R 3.3.0)
## nlme 3.1-131 2017-02-06 CRAN (R 3.3.3)
## plotly * 4.6.0 2017-04-25 CRAN (R 3.3.3)
## plyr 1.8.4 2016-06-08 CRAN (R 3.3.0)
## psych 1.7.3.21 2017-03-22 CRAN (R 3.3.2)
## purrr * 0.2.2 2016-06-18 CRAN (R 3.3.0)
## R6 2.2.0 2016-10-05 CRAN (R 3.3.0)
## Rcpp 0.12.10 2017-03-19 cran (@0.12.10)
## readr * 1.1.0 2017-03-22 cran (@1.1.0)
## readxl 0.1.1 2016-03-28 CRAN (R 3.3.0)
## reshape2 1.4.2 2016-10-22 CRAN (R 3.3.0)
## rJava * 0.9-8 2016-01-07 CRAN (R 3.3.3)
## rlang 0.0.0.9018 2017-05-01 Github (hadley/rlang@460323e)
## rmarkdown 1.3 2016-12-21 CRAN (R 3.3.2)
## rprojroot 1.2 2017-01-16 CRAN (R 3.3.2)
## rvest 0.3.2 2016-06-17 CRAN (R 3.3.0)
## scales 0.4.1 2016-11-09 CRAN (R 3.3.1)
## shiny 1.0.0 2017-01-12 CRAN (R 3.3.2)
## stringi 1.1.2 2016-10-01 CRAN (R 3.3.0)
## stringr * 1.2.0 2017-02-18 CRAN (R 3.3.2)
## tibble * 1.3.0.9001 2017-05-01 Github (tidyverse/tibble@08af6b0)
## tidyr * 0.6.1 2017-01-10 CRAN (R 3.3.2)
## tidyverse * 1.1.1 2017-01-27 CRAN (R 3.3.2)
## viridisLite 0.2.0 2017-03-24 cran (@0.2.0)
## withr 1.0.2 2016-06-20 CRAN (R 3.3.0)
## XLConnect * 0.2-12 2016-06-24 CRAN (R 3.3.0)
## XLConnectJars * 0.2-12 2016-06-24 CRAN (R 3.3.0)
## xml2 1.1.1 2017-01-24 CRAN (R 3.3.2)
## xtable 1.8-2 2016-02-05 CRAN (R 3.3.0)
## yaml 2.1.14 2016-11-12 cran (@2.1.14)
In fact this is the exact trouble I went through when building the app. It’s easier to work on the graph portion in a static environment first, before incorporating the Shiny components.↩